home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / PHPUnit / Skeleton.php < prev    next >
PHP Script  |  2004-10-01  |  13KB  |  407 lines

  1. <?php
  2. //
  3. // +------------------------------------------------------------------------+
  4. // | PEAR :: PHPUnit                                                        |
  5. // +------------------------------------------------------------------------+
  6. // | Copyright (c) 2002-2004 Sebastian Bergmann <sb@sebastian-bergmann.de>. |
  7. // +------------------------------------------------------------------------+
  8. // | This source file is subject to version 3.00 of the PHP License,        |
  9. // | that is available at http://www.php.net/license/3_0.txt.               |
  10. // | If you did not receive a copy of the PHP license and are unable to     |
  11. // | obtain it through the world-wide-web, please send a note to            |
  12. // | license@php.net so we can mail you a copy immediately.                 |
  13. // +------------------------------------------------------------------------+
  14. //
  15. // $Id: Skeleton.php,v 1.2 2004/09/28 06:52:47 sebastian Exp $
  16. //
  17.  
  18. /**
  19.  * Class for creating a PHPUnit_TestCase skeleton file.
  20.  *
  21.  * This class will take a classname as a parameter on construction and will
  22.  * create a PHP file that contains the skeleton of a PHPUnit_TestCase
  23.  * subclass. The test case will contain a test foreach method of the class.
  24.  * Methods of the parent class will, by default, be excluded from the test
  25.  * class. Passing and optional construction parameter will include them.
  26.  *
  27.  * Example
  28.  *
  29.  *   <?php
  30.  *   require_once 'PHPUnit/Skeleton.php';
  31.  *   $ps = new PHPUnit_Skeleton('PHPUnit_Skeleton', 'PHPUnit/Skeleton.php');
  32.  *   
  33.  *   // Generate the test class.
  34.  *   // Default settings will not include any parent class methods, but
  35.  *   // will include private methods.
  36.  *   $ps->createTestClass();
  37.  *   
  38.  *   // Write the new test class to file.
  39.  *   // By default, code to run the test will be included.
  40.  *   $ps->writeTestClass();
  41.  *   ?>
  42.  *   
  43.  * Now open the skeleton class and fill in the details.
  44.  * If you run the test as is, all tests will fail and 
  45.  * you will see plenty of undefined constant errors.
  46.  *   
  47.  * @author      Scott Mattocks <scott@crisscott.com>
  48.  * @copyright   Copyright © 2002-2004 Sebastian Bergmann <sb@sebastian-bergmann.de>
  49.  * @license     http://www.php.net/license/3_0.txt The PHP License, Version 3.0
  50.  * @category    PHP
  51.  * @package     PHPUnit
  52.  */
  53. class PHPUnit_Skeleton {
  54.     /**
  55.      * Path to the class file to create a skeleton for.
  56.      * @var string
  57.      */
  58.     var $classPath;
  59.  
  60.     /**
  61.      * The name of the class
  62.      * @var string
  63.      */
  64.     var $className;
  65.  
  66.     /**
  67.      * Path to the configuration file needed by class to test.
  68.      * @var string
  69.      */
  70.     var $configFile;
  71.  
  72.     /**
  73.      * Whether or not to include the methods of the parent class when testing.
  74.      * @var boolean
  75.      */
  76.     var $includeParents;
  77.  
  78.     /**
  79.      * Whether or not to test private methods.
  80.      * @var boolean
  81.      */
  82.     var $includePrivate;
  83.  
  84.     /**
  85.      * The test class that will be created.
  86.      * @var string
  87.      */
  88.     var $testClass;
  89.  
  90.     /**
  91.      * Constructor. Sets the class members and check that the class
  92.      * to test is accessible.
  93.      *
  94.      * @access public
  95.      * @param  string  $className
  96.      * @param  string  $classPath
  97.      * @param  boolean $includeParents Wheter to include the parent's methods in the test.
  98.      * @return void
  99.      */
  100.     function PHPUnit_Skeleton($className, $classPath, $includeParents = FALSE, $includePrivate = TRUE) {
  101.         // Set up the members.
  102.         if (@is_readable($classPath)) {
  103.             $this->className = $className;
  104.             $this->classPath = $classPath;
  105.         } else {
  106.             $this->_handleErrors($classPath . ' is not readable. Cannot create test class.');
  107.         }
  108.  
  109.         // Do we want to include parent methods?
  110.         $this->includeParents = $includeParents;
  111.  
  112.         // Do we want to allow private methods?
  113.         $this->includePrivate = $includePrivate;
  114.     }
  115.  
  116.     /**
  117.      * The class to test may require a special config file before it can be
  118.      * instantiated. This method lets you set that file.
  119.      *
  120.      * @access public
  121.      * @param  string $configPath
  122.      * @return void
  123.      */
  124.     function setConfigFile($configFile) {
  125.         // Check that the file is readable
  126.         if (@is_readable($configFile)) {
  127.             $this->configFile = $configFile;
  128.         } else {
  129.             $this->_handleErrors($configFile . ' is not readable. Cannot create test class.');
  130.         }
  131.     }
  132.  
  133.     /**
  134.      * Create the code that will be the skeleton of the test case.
  135.      *
  136.      * The test case must have a clss definition, one var, a constructor
  137.      * setUp, tearDown, and methods. Optionally and by default the code
  138.      * to run the test is added when the class is written to file.
  139.      *
  140.      * @access public
  141.      * @param  none
  142.      * @return void
  143.      */
  144.     function createTestClass() {
  145.         // Instantiate the object.
  146.         if (isset($this->configFile)) {
  147.             require_once $this->configFile;
  148.         }
  149.  
  150.         require_once $this->classPath;
  151.  
  152.         // Get the methods.
  153.         $classMethods = get_class_methods($this->className);
  154.  
  155.         // Remove the parent methods if needed.
  156.         if (!$this->includeParents) {
  157.             $parentMethods = get_class_methods(get_parent_class($this->className));
  158.  
  159.             if (count($parentMethods)) {
  160.                 $classMethods = array_diff($classMethods, $parentMethods);
  161.             }
  162.         }
  163.  
  164.         // Create the class definition, constructor, setUp and tearDown.
  165.         $this->_createDefinition();
  166.         $this->_createConstructor();
  167.         $this->_createSetUpTearDown();
  168.  
  169.         if (count($classMethods)) {
  170.             // Foreach method create a test case.
  171.             foreach ($classMethods as $method) {
  172.                 // Unless it is the constructor.
  173.                 if (strcasecmp($this->className, $method) !== 0) {
  174.                   // Check for private methods.
  175.                   if (!$this->includePrivate && strpos($method, '_') === 0) {
  176.                       continue;
  177.                   } else {
  178.                       $this->_createMethod($method);
  179.                   }
  180.                 }
  181.             }
  182.         }
  183.  
  184.         // Finis off the class.
  185.         $this->_finishClass();
  186.     }
  187.  
  188.     /**
  189.      * Create the class definition.
  190.      *
  191.      * The definition consist of a header comment, require statment
  192.      * for getting the PHPUnit file, the actual class definition,
  193.      * and the definition of the class member variable.
  194.      *
  195.      * All of the code needed for the new class is stored in the
  196.      * testClass member.
  197.      *
  198.      * @access private
  199.      * @param  none
  200.      * @return void
  201.      */
  202.     function _createDefinition() {
  203.         // Create header comment.
  204.         $this->testClass =
  205.           "/**\n" .
  206.           " * PHPUnit test case for " . $this->className . "\n" .
  207.           " * \n" .
  208.           " * The method skeletons below need to be filled in with \n" .
  209.           " * real data so that the tests will run correctly. Replace \n" .
  210.           " * all EXPECTED_VAL and PARAM strings with real data. \n" .
  211.           " * \n" .
  212.           " * Created with PHPUnit_Skeleton on " . date('Y-m-d') . "\n" .
  213.           " */\n";
  214.  
  215.         // Add the require statements.
  216.         $this->testClass .= "require_once 'PHPUnit.php';\n";
  217.  
  218.         // Add the class definition and variable definition.
  219.         $this->testClass .=
  220.           "class " . $this->className . "Test extends PHPUnit_TestCase {\n\n" .
  221.           "    var \$" . $this->className . ";\n\n";
  222.     }
  223.  
  224.     /**
  225.      * Create the class constructor. (PHP4 style)
  226.      *
  227.      * The constructor simply calls the PHPUnit_TestCase method.
  228.      * This code is taken from the PHPUnit documentation.
  229.      *
  230.      * All of the code needed for the new class is stored in the
  231.      * testClass member.
  232.      *
  233.      * @access private
  234.      * @param  none
  235.      * @return void
  236.      */
  237.     function _createConstructor() {
  238.         // Create the test class constructor.
  239.         $this->testClass.=
  240.           "    function " . $this->className . "Test(\$name)\n" .
  241.           "    {\n" .
  242.           "        \$this->PHPUnit_TestCase(\$name);\n" .
  243.           "    }\n\n";
  244.     }
  245.  
  246.     /**
  247.      * Create setUp and tearDown methods.
  248.      *
  249.      * The setUp method creates the instance of the object to test.
  250.      * The tearDown method releases the instance.
  251.      * This code is taken from the PHPUnit documentation.
  252.      *
  253.      * All of the code needed for the new class is stored in the
  254.      * testClass member.
  255.      *
  256.      * @access private
  257.      * @param  none
  258.      * @return void
  259.      */
  260.     function _createSetUpTearDown() {
  261.         // Create the setUp method.
  262.         $this->testClass .=
  263.           "    function setUp()\n" .
  264.           "    {\n";
  265.  
  266.         if (isset($this->configFile)) {
  267.             $this->testClass .=
  268.             "        require_once '" . $this->configFile . "';\n";
  269.         }
  270.  
  271.         $this->testClass .=
  272.           "        require_once '" . $this->classPath . "';\n" .
  273.           "        \$this->" . $this->className . " =& new " . $this->className . "(PARAM);\n" .
  274.           "    }\n\n";
  275.  
  276.         // Create the tearDown method.
  277.         $this->testClass .=
  278.           "    function tearDown()\n" .
  279.           "    {\n" .
  280.           "        unset(\$this->" . $this->className . ");\n" .
  281.           "    }\n\n";
  282.     }
  283.  
  284.     /**
  285.      * Create a basic skeleton for test methods.
  286.      *
  287.      * This code is taken from the PHPUnit documentation.
  288.      *
  289.      * All of the code needed for the new class is stored in the
  290.      * testClass member.
  291.      *
  292.      * @access private
  293.      * @param  none
  294.      * @return void
  295.      */
  296.     function _createMethod($methodName) {
  297.         // Create a test method.
  298.         $this->testClass .=
  299.           "    function test" . $methodName . "()\n" .
  300.           "    {\n" .
  301.           "        \$result   = \$this->" . $this->className . "->" . $methodName . "(PARAM);\n" .
  302.           "        \$expected = EXPECTED_VAL;\n" .
  303.           "        \$this->assertEquals(\$result, \$expected);\n" .
  304.           "    }\n\n";
  305.     }
  306.  
  307.     /**
  308.      * Add the closing brace needed for a proper class definition.
  309.      *
  310.      * All of the code needed for the new class is stored in the
  311.      * testClass member.
  312.      *
  313.      * @access private
  314.      * @param  none
  315.      * @return void
  316.      */
  317.     function _finishClass() {
  318.         // Close off the class.
  319.         $this->testClass.= "}\n";
  320.     }
  321.  
  322.     /**
  323.      * Create the code that will actually run the test.
  324.      *
  325.      * This code is added by default so that the test can be run
  326.      * just by running the file. To have it not added pass false
  327.      * as the second parameter to the writeTestClass method.
  328.      * This code is taken from the PHPUnit documentation.
  329.      *
  330.      * All of the code needed for the new class is stored in the
  331.      * testClass member.
  332.      *
  333.      * @access private
  334.      * @param  none
  335.      * @return void
  336.      */
  337.     function _createTest() {
  338.         // Create a call to the test.
  339.         $test =
  340.           "// Running the test.\n" .
  341.           "\$suite  = new PHPUnit_TestSuite('" . $this->className . "Test');\n" .
  342.           "\$result = PHPUnit::run(\$suite);\n" .
  343.           "echo \$result->toString();\n";
  344.  
  345.         return $test;
  346.     }
  347.  
  348.     /**
  349.      * Write the test class to file.
  350.      *
  351.      * This will write the test class created using the createTestClass
  352.      * method to a file called <className>Test.php. By default the file
  353.      * is written to the current directory and will have code to run
  354.      * the test appended to the bottom of the file.
  355.      *
  356.      * @access public
  357.      * @param  string  $destination The directory to write the file to.
  358.      * @param  boolean $addTest     Wheter to add the test running code.
  359.      * @return void
  360.      */
  361.     function writeTestClass($destination = './', $addTest = TRUE) {
  362.         // Check for something to write to file.
  363.         if (!isset($this->testClass)) {
  364.             $this->_handleErrors('Noting to write.', PHPUS_WARNING);
  365.             return;
  366.         }
  367.  
  368.         // Open the destination file.
  369.         $fp = fopen($destination . $this->className . 'Test.php', 'w');
  370.         fwrite($fp, "<?php\n");
  371.  
  372.         // Write the test class.
  373.         fwrite($fp, $this->testClass);
  374.  
  375.         // Add the call to test the class in the file if we were asked to.
  376.         if ($addTest) {
  377.             fwrite($fp, $this->_createTest());
  378.         }
  379.  
  380.         // Close the file.
  381.         fwrite($fp, "?>\n");
  382.         fclose($fp);
  383.     }
  384.  
  385.     /**
  386.      * Error handler.
  387.      *
  388.      * This method should be rewritten to use the prefered error
  389.      * handling method. (PEAR_ErrorStack)
  390.      *
  391.      * @access private
  392.      * @param  string  $message The error message.
  393.      * @param  integer $type    An indication of the severity of the error.
  394.      * @return void             Code may cause PHP to exit.
  395.      */
  396.     function _handleErrors($message, $type = E_USER_ERROR) {
  397.         // For now just echo the message.
  398.         echo $message;
  399.  
  400.         // Check to see if we should quit.
  401.         if ($type == E_USER_ERROR) {
  402.             exit;
  403.         }
  404.     }
  405. }
  406. ?>
  407.